﻿using System;
using System.Diagnostics;
using System.Threading;
using System.Threading.Tasks;
using System.Web.Http;
using System.Web.Http.Description;
using BrnMall.Core;
using BrnMall.Manager.Manager.Distribution;
using BrnMall.Manager.Manager.Store;
using BrnMall.Manager.Manager.User;
using BrnMall.Manager.Manager.WeApp;
using BrnMall.Services;
using BrnMall.WeiXin.Sdk;
using QIDong.WeApp.Models;
using QIDong.WeApp.Util;
using WeiTap.Restful;

namespace QIDong.WeApp.Controllers
{
    /// <summary>
    /// 账号控制器类
    /// </summary>
    public class AccountController : WebApi
    {
        /// <summary>
        /// 微信登录
        /// </summary>
        /// <param name="code"></param>
        /// <param name="storeid">商户ID</param>
        /// <param name="weAppId">小程序配置ID</param>
        /// <returns></returns>
        public PartUserInfo WxLogin(string code, int storeid, int weAppId = 0)
        {
            if (string.IsNullOrEmpty(code))
                throw new Exception("code为空");
            try
            {
                var wxapp = StoreWxAppManager.GetStoreDefaultWxAppById(storeid, weAppId);
                if (string.IsNullOrEmpty(wxapp?.WeAppId) || string.IsNullOrEmpty(wxapp.WeAppSecret))
                    throw new Exception("请登录商户后台设置小程序AppID,AppSecret");
                var session = WeiXinSdk.GetSessionResult(code, wxapp.WeAppId, wxapp.WeAppSecret);
                if (session.errcode != 0)
                    throw new Exception(session.errmsg);
                var uid = OAuths.GetUidByOpenIdAndServer(session.OpenId, "weapp");
                if (uid < 1)
                    throw new ApiException(ExceptionCode.DataNotFound, "user");
                var partUserInfo = Users.GetPartUserById(uid);
                if (partUserInfo.RegisterFromStoreId == 0)
                {
                    partUserInfo.RegisterFromStoreId = storeid;
                }
                if (partUserInfo.UserRid == 1) //当用户等级是禁止访问等级时
                {
                    if (partUserInfo.LiftBanTime > DateTime.Now)//达到解禁时间
                    {
                        UserRankInfo userRankInfo = UserRanks.GetUserRankByCredits(partUserInfo.PayCredits, partUserInfo.RegisterFromStoreId);

                        Users.UpdateUserRankByUid(partUserInfo.Uid, userRankInfo?.UserRid ?? 0);
                        partUserInfo.UserRid = userRankInfo?.UserRid ?? 0;


                    }
                    else
                    {
                        throw new Exception("您的账号当前被锁定,不能访问");
                    }
                }
                //发放登录积分
                Credits.SendLoginCredits(storeid, ref partUserInfo, DateTime.Now);
                Users.UpdatePartUser(partUserInfo);
                return partUserInfo;
            }
            catch (Exception e)
            {
                Console.WriteLine(e);
                throw;
            }
        }



        /// <summary>
        /// 小程序注册
        /// </summary>
        /// <param name="code"></param>
        /// <param name="encryptedData"></param>
        /// <param name="iv"></param>
        /// <param name="storeid">店铺ID</param>
        /// <param name="weAppId">小程序配置ID</param>
        /// <returns></returns>
        public bool WxRegister(string code, string encryptedData, string iv, int storeid, int weAppId = 0)
        {
            try
            {

                var wxapp = StoreWxAppManager.GetStoreDefaultWxAppById(storeid, weAppId);
                var session = WeiXinSdk.GetSessionResult(code, wxapp.WeAppId, wxapp.WeAppSecret);
                var wxUser = WeiXinSdk.DecryptUserInfo(session.Session_Key, encryptedData, iv);
                var uid = OAuths.GetUidByOpenIdAndServer(session.OpenId, "weapp");
                if (uid > 0)
                {
                    var partUserInfo = Users.GetPartUserById(uid);
                    partUserInfo.Avatar = wxUser.avatarUrl;
                    partUserInfo.NickName = wxUser.NickName;
                    Users.UpdatePartUser(partUserInfo);
                    return true;
                }
                var userInfo = OAuths.CreateOAuthUser(DateTime.Now.ToString("yyMMddHHmmssms"), "weapp", wxUser.OpenId, "weapp", 0);
                //添加用户失败
                if (userInfo == null || userInfo.Uid < 1)
                    throw new Exception("创建用户失败,请联系管理员");
                int gender = 0;
                int.TryParse(wxUser.Gender, out gender);
                userInfo.Gender = gender;
                userInfo.NickName = wxUser.NickName;
                userInfo.Avatar = wxUser.avatarUrl;
                userInfo.RegisterFromStoreId = storeid;
                userInfo.WeAppId = weAppId;

                //发放注册积分
                Credits.SendRegisterCredits(storeid, ref userInfo, DateTime.Now);
                Users.UpdatePartUser(userInfo);
                return true;
            }
            catch (Exception e)
            {
                Trace.TraceInformation("{0},{1},{2},{3}", code, encryptedData, iv, storeid);
                Trace.TraceError(e.Message);
                Trace.TraceError(e.Source);
                throw;
            }

        }

        #region 第三方平台注册登录
        /// <summary>
        /// 小程序第三方平台微信登录
        /// </summary>
        /// <param name="code"></param>
        /// <param name="storeid">商户ID</param>
        /// <param name="storeAppId">企动小程序ID</param>
        /// <returns></returns>
        public PartUserInfo WxOpenLogin(string code, int storeAppId, int storeid)
        {
            if (string.IsNullOrEmpty(code))
                throw new Exception("code为空");
            try
            {
                var openPlatform = WeApplicationManager.GetDefaultApplicationPlatform();
                var auth = AppAuthorizationManager.GetAppAuthorizationByStoreAppId(storeAppId);
                if (auth == null)
                    throw new Exception("未找到相关的授权信息");
                var session = WeiXinSdk.GetSessionResult(auth.Authorizer_Appid, code, openPlatform.AppId, openPlatform.Component_Access_Token);
                if (session.errcode != 0)
                    throw new Exception($"[{session.errcode}]{session.errmsg}");
                var uid = OAuths.GetUidByOpenIdAndServer(session.OpenId, "weapp");
                if (uid < 1)
                {
                    var userInfo = OAuths.CreateOAuthUser(DateTime.Now.ToString("yyMMddHHmmssms"), "weapp", session.OpenId, "weapp", 0);
                    //添加用户失败
                    if (userInfo == null || userInfo.Uid < 1)
                        throw new Exception("创建用户失败,请联系管理员");
                 
                    userInfo.Gender = 0;
                    userInfo.NickName = "昵称";
                    userInfo.Avatar = "http://static.711688.net.cn/images/userdefault.png";
                    userInfo.RegisterFromStoreId = storeid;
                    userInfo.StoreAppId = storeAppId;
                    Users.UpdatePartUser(userInfo);
                    return userInfo;
                }
                
                var partUserInfo = Users.GetPartUserById(uid);

                partUserInfo.RegisterFromStoreId = storeid;
                partUserInfo.StoreAppId = storeAppId;
                Users.UpdatePartUser(partUserInfo);
                DistributorManager.SyncUserInfo(partUserInfo.Uid, partUserInfo.Avatar, partUserInfo.NickName);
                //发放登录积分
                Credits.SendLoginCredits(storeid, ref partUserInfo, DateTime.Now);
                return partUserInfo;
            }
            catch (Exception e)
            {
                Console.WriteLine(e);
                throw;
            }
        }
        /// <summary>
        /// 小程序第三方平台注册
        /// </summary>
        /// <param name="code"></param>
        /// <param name="encryptedData"></param>
        /// <param name="iv"></param>
        /// <param name="storeid">店铺ID</param>
        /// <param name="storeAppId">企动小程序ID</param>
        /// <returns></returns>
        public bool WxOpenRegister(string code, string encryptedData, string iv, int storeid, int storeAppId)
        {
            try
            {
                var openPlatform = WeApplicationManager.GetDefaultApplicationPlatform();
                var auth = AppAuthorizationManager.GetAppAuthorizationByStoreAppId(storeAppId);
                var session = WeiXinSdk.GetSessionResult(auth.Authorizer_Appid, code, openPlatform.AppId, openPlatform.Component_Access_Token);
                var wxUser = WeiXinSdk.DecryptUserInfo(session.Session_Key, encryptedData, iv);
                Trace.TraceInformation($"session.Session_Key:{session.Session_Key}");
                Trace.TraceInformation($"session.OpenId:{session.OpenId}");
                var uid = OAuths.GetUidByOpenIdAndServer(session.OpenId, "weapp");
                if (uid > 0)
                {
                    var partUserInfo = Users.GetPartUserById(uid);
                    partUserInfo.Avatar = wxUser.avatarUrl;
                    partUserInfo.NickName = wxUser.NickName;
                    Users.UpdatePartUser(partUserInfo);
                    return true;
                }
                var userInfo = OAuths.CreateOAuthUser(DateTime.Now.ToString("yyMMddHHmmssms"), "weapp", wxUser.OpenId, "weapp", 0);
                //添加用户失败
                if (userInfo == null || userInfo.Uid < 1)
                    throw new Exception("创建用户失败,请联系管理员");
                int gender = 0;
                int.TryParse(wxUser.Gender, out gender);
                userInfo.Gender = gender;
                userInfo.NickName = wxUser.NickName;
                userInfo.Avatar = wxUser.avatarUrl;
                userInfo.RegisterFromStoreId = storeid;
                userInfo.StoreAppId = storeAppId;
                Users.UpdatePartUser(userInfo);
                //发放注册积分
                Credits.SendRegisterCredits(storeid, ref userInfo, DateTime.Now);
                Task.Factory.StartNew(() => WebIMUtil.ImportUser(userInfo), CancellationToken.None)
                    .ConfigureAwait(false);
                Task.Factory.StartNew(() => WebIMUtil.UpdateUser(userInfo), CancellationToken.None)
                    .ConfigureAwait(false);
                return true;
            }
            catch (Exception e)
            {
                Trace.TraceInformation("{0},{1},{2},{3}", code, encryptedData, iv, storeid);
                Trace.TraceError(e.Message);
                Trace.TraceError(e.Source);
                throw;
            }

        }


        #endregion
        

        /// <summary>
        /// 设置当前用户点击分享注册的来源人
        /// </summary>
        /// <param name="uid"></param>
        /// <param name="fromuid">分享人</param>
        /// <returns></returns>
        public bool SetFromUid(int uid, int fromuid)
        {
            try
            {

                return true;
            }
            catch (Exception e)
            {
                Trace.TraceError(e.Message);
                throw;
            }
        }
        /// <summary>
        /// 通过第三方账号获取用户的基本信息
        /// </summary>
        /// <param name="openId">第三方账号</param>
        /// <param name="server">第三方平台，小程序:weapp,订阅宝:dyb</param>
        /// <returns></returns>
        public PartUserInfo GetUserFromOpenId(string openId, string server)
        {
            var auth = OAuths.GetUidByOpenIdAndServer(openId, server);
            return Users.GetPartUserById(auth);
        }
        #region 店铺管理员
        /// <summary>
        /// 登录
        /// </summary>
        /// <param name="username"></param>
        /// <param name="password"></param>
        /// <returns></returns>
        [HttpPost]
        public PartUserInfo AdminLogin(string username, string password)
        {
            var partUserInfo = Users.GetPartUserByName(username);
            if (partUserInfo == null) throw new ApiException(ExceptionCode.DataNotFound);
            if (Users.CreateUserPassword(password, partUserInfo.Salt) != partUserInfo.Password)
            {
                throw new ApiException(ExceptionCode.DataInvalid, "密码");
            }
            return partUserInfo;
        }
        #endregion

        #region 获取用户微信绑定的手机号
        /// <summary>
        /// 获取用户微信绑定的手机号
        /// </summary>
        /// <param name="code"></param>
        /// <param name="encryptedData"></param>
        /// <param name="iv"></param>
        /// <param name="storeid"></param>
        /// <param name="storeAppId"></param>
        /// <returns></returns>
        public string GetPhoneNumber(string code, string encryptedData, string iv, int storeid, int storeAppId)
        {
            try
            {
                var openPlatform = WeApplicationManager.GetDefaultApplicationPlatform();
                var auth = AppAuthorizationManager.GetAppAuthorizationByStoreAppId(storeAppId);
                var session = WeiXinSdk.GetSessionResult(auth.Authorizer_Appid, code, openPlatform.AppId, openPlatform.Component_Access_Token);
                if (session == null)
                    throw new Exception("微信登录失败");
                Trace.TraceInformation($"session.Session_Key:{session.Session_Key} , session.OpenId:{session.OpenId}");
                var wxUser = WeiXinSdk.DecryptUserInfo(session.Session_Key, encryptedData, iv);
                var uid = OAuths.GetUidByOpenIdAndServer(session.OpenId, "weapp");
                PartUserInfo partUserInfo = Users.GetPartUserById(uid);
                if (uid > 0)
                {
                    partUserInfo.Mobile = wxUser.PhoneNumber;
                    Users.UpdatePartUser(partUserInfo);
                }
                return wxUser != null ? wxUser.PhoneNumber : "";
            }
            catch (Exception ex)
            {
                Trace.TraceInformation($"Account.GetPhoneNumber('{code}','{encryptedData}','{iv}',{storeid},{storeAppId})失败：{ex.Message}");
                throw;
            }
        }
        #endregion

        #region 在线状态
        /// <summary>
        /// 离线
        /// </summary>
        /// <param name="uid"></param>
        public void OffLine(int uid)
        {
            UsersManager.UpdateUserIMState(uid, false);
        }
        /// <summary>
        /// 在线
        /// </summary>
        /// <param name="uid"></param>
        /// <param name="sid"></param>
        public void OnLine(int uid)
        {
            UsersManager.UpdateUserIMState(uid, true);
        }

        #endregion
    }
}
